package net.goutalk.glcs.module.form.utils;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import net.goutalk.glcs.common.constant.FormComponentConstant;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.model.generator.ComponentConfig;
import net.goutalk.glcs.common.model.generator.LayoutOptionModel;
import net.goutalk.glcs.common.utils.DatasourceUtil;
import net.goutalk.glcs.module.generator.entity.TableConfig;
import net.goutalk.glcs.module.generator.entity.TableFieldConfig;
import net.goutalk.glcs.module.generator.entity.TableStructureConfig;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;


/**
 * 代码模板模块工具类
 */
public class FromTemplateUtil {

    /**
     * 数据优先 根据配置 构建表结构配置  tableConfig 转 tableStructureConfigs
     *
     * @param list            组件配置
     * @param mainTableConfig 主表配置
     * @return 表结构配置
     */
    public static List<TableStructureConfig> wrapperTableStructureConfig(List<ComponentConfig> list, TableConfig mainTableConfig) {
        List<TableStructureConfig> tableStructureConfigs = new ArrayList<>();

        TableStructureConfig mainTableStructureConfig = new TableStructureConfig();
        mainTableStructureConfig.setIsMain(true);
        mainTableStructureConfig.setTableName(mainTableConfig.getTableName());
        List<TableFieldConfig> mainTableFieldConfigs = new ArrayList<>();
        mainTableStructureConfig.setTableFieldConfigs(mainTableFieldConfigs);


        //遍历所有所有组件中的子表单组件
        list.forEach(componentConfig -> {

            //是否为子表单组件
            if (StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.FORM_COMPONENT_TYPE)) {
                getChildTableStructureConfig(tableStructureConfigs, componentConfig);
            } else {
                //是否为选项卡 或者 布局组件
                if (
                        StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.GRID_COMPONENT_TYPE) ||
                                StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.TAB_COMPONENT_TYPE) ||
                                StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.CARD_COMPONENT_TYPE)
                ) {
                    //遍历所有布局数据
                    getLayoutComponentsStructureConfig(tableStructureConfigs, mainTableFieldConfigs, componentConfig);

                } else {
                    TableFieldConfig tableFieldConfig = new TableFieldConfig();
                    tableFieldConfig.setFieldName(componentConfig.getBindField());
                    tableFieldConfig.setFieldComment(componentConfig.getLabel());
                    mainTableFieldConfigs.add(tableFieldConfig);
                }
            }


        });
        tableStructureConfigs.add(mainTableStructureConfig);
        //将转换好的表结构配置存入到dto的FormJson  然后存入数据库
        return tableStructureConfigs;


    }


    /**
     * 代码优先  根据配置 构建表配置  tableStructureConfigs 转 tableConfig
     * @param tableStructureConfigs 表结构配置
     * @return 表配置
     */
    public static List<TableConfig> wrapperTableConfig(String dbId, List<TableStructureConfig> tableStructureConfigs) {
        List<TableConfig> tableConfigs = new ArrayList<>();
        DbType dbType = DatasourceUtil.getDbType(dbId);
        boolean isUpperCase = ArrayUtils.contains(new DbType[]{DbType.ORACLE, DbType.ORACLE_12C, DbType.DM}, dbType);
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {

            //因为要统一自定义表单存入到数据库的json格式  所以 在这里需要将codefirst的表结构配置json格式转换成datafirst的json格式
            // TableStructureConfig -> TableConfig
            TableConfig tableConfig = new TableConfig();
            tableConfig.setTableName(tableStructureConfig.getTableName());
            tableConfig.setIsMain(tableStructureConfig.getIsMain());
            tableConfig.setPkField(isUpperCase ? StringUtils.upperCase(GlobalConstant.DEFAULT_PK) : GlobalConstant.DEFAULT_PK);
            tableConfig.setPkType(GlobalConstant.DEFAULT_PK_TYPE);
            tableConfig.setRelationField(tableStructureConfig.getIsMain() ? null : isUpperCase ? StringUtils.upperCase(GlobalConstant.DEFAULT_FK) : GlobalConstant.DEFAULT_FK);
            tableConfig.setRelationTableField(tableStructureConfig.getIsMain() ? null : isUpperCase ? StringUtils.upperCase(GlobalConstant.DEFAULT_PK) : GlobalConstant.DEFAULT_PK);
            tableConfigs.add(tableConfig);
        }
        return tableConfigs;
    }


    /**
     * 获取子表单组件的表结构配置
     *
     * @param tableStructureConfigs 所有表结构配置
     * @param componentConfig       子表单组件
     */
    public static void getChildTableStructureConfig(List<TableStructureConfig> tableStructureConfigs, ComponentConfig componentConfig) {

        TableStructureConfig tableStructureConfig = new TableStructureConfig();
        tableStructureConfig.setIsMain(true);
        tableStructureConfig.setTableName(componentConfig.getBindTable());
        List<TableFieldConfig> tableFieldConfigs = new ArrayList<>();
        tableStructureConfig.setTableFieldConfigs(tableFieldConfigs);

        //是否为子表单组件
        if (StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.FORM_COMPONENT_TYPE)) {
            //子表单不能再包含子表单
            componentConfig.getChildren().forEach(child -> {
                TableFieldConfig tableFieldConfig = new TableFieldConfig();
                tableFieldConfig.setFieldName(child.getBindField());
                tableFieldConfig.setFieldComment(child.getLabel());
                tableFieldConfigs.add(tableFieldConfig);
            });
        }

        tableStructureConfigs.add(tableStructureConfig);
    }

    /**
     * 获取布局组件下的所有组件表结构配置
     *
     * @param tableStructureConfigs
     * @param mainTableFieldConfigs
     * @param componentConfig
     */
    public static void getLayoutComponentsStructureConfig(List<TableStructureConfig> tableStructureConfigs, List<TableFieldConfig> mainTableFieldConfigs, ComponentConfig componentConfig) {
        //是否为子表单组件
        if (StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.FORM_COMPONENT_TYPE)) {
            getChildTableStructureConfig(tableStructureConfigs, componentConfig);
        } else {
            //是否为选项卡 或者 布局组件
            if (
                    StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.GRID_COMPONENT_TYPE) ||
                            StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.TAB_COMPONENT_TYPE) ||
                            StrUtil.equalsIgnoreCase(componentConfig.getType(), FormComponentConstant.CARD_COMPONENT_TYPE)
            ) {
                //遍历所有布局数据
                for (LayoutOptionModel layoutOptionModel : componentConfig.getLayout()) {
                    //遍历布局下  所有的组件
                    for (ComponentConfig config : layoutOptionModel.getList()) {
                        //是否为子表单组件
                        if (StrUtil.equalsIgnoreCase(config.getType(), FormComponentConstant.FORM_COMPONENT_TYPE)) {
                            getChildTableStructureConfig(tableStructureConfigs, config);
                        }
                        //是否为选项卡 或者 布局组件
                        else if (
                                StrUtil.equalsIgnoreCase(config.getType(), FormComponentConstant.GRID_COMPONENT_TYPE) ||
                                        StrUtil.equalsIgnoreCase(config.getType(), FormComponentConstant.TAB_COMPONENT_TYPE) ||
                                        StrUtil.equalsIgnoreCase(config.getType(), FormComponentConstant.CARD_COMPONENT_TYPE)
                        ) {
                            getLayoutComponentsStructureConfig(tableStructureConfigs, mainTableFieldConfigs, config);
                        } else {
                            TableFieldConfig tableFieldConfig = new TableFieldConfig();
                            tableFieldConfig.setFieldName(config.getBindField());
                            tableFieldConfig.setFieldComment(config.getLabel());
                            mainTableFieldConfigs.add(tableFieldConfig);
                        }
                    }
                }

            } else {
                TableFieldConfig tableFieldConfig = new TableFieldConfig();
                tableFieldConfig.setFieldName(componentConfig.getBindField());
                tableFieldConfig.setFieldComment(componentConfig.getLabel());
                mainTableFieldConfigs.add(tableFieldConfig);
            }
        }


    }


}
